﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Speech.AudioFormat;
using System.Speech.Synthesis;
using System.Threading.Tasks;
using System.IO;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
using Microsoft.Net.Http.Headers;

namespace TTSTest.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TextToSpeechController : ControllerBase
    {
        private readonly IWebHostEnvironment _hostingEnvironment;
        private readonly ILogger<TextToSpeechController> _logger;
        public TextToSpeechController(IWebHostEnvironment hostingEnvironment, ILogger<TextToSpeechController> logger)
        {
            _hostingEnvironment = hostingEnvironment;
            _logger = logger;
        }

        private static readonly object obj = new();

        [HttpGet]
        public ActionResult get(string text, int speed = -3, string name = "")
        {
            try
            {
                if (speed > 10 || speed < -10)
                {
                    throw new Exception("语速设置异常，语速取值范围为-10 - 10！");
                }
                lock (obj)
                {
                    if (text.Length > 65535)
                    {
                        throw new Exception("文字长度太长了，请将文字控制在65535个字符之内！");
                    }
                    text = GetVoidText(text, name);
                    string fileName = GetMD5(text);
                    string filePath = _hostingEnvironment.ContentRootPath + $"\\wwwroot\\speech\\{fileName}.wav";
                    var stream = new MemoryStream();
                    try
                    {
                        using SpeechSynthesizer synth = new();
                        synth.Rate = speed;
                        synth.Volume = 100;
                        //synth.SetOutputToWaveFile(filePath, new SpeechAudioFormatInfo(32000, AudioBitsPerSample.Sixteen, AudioChannel.Mono));
                        synth.SetOutputToWaveStream(stream);
                        PromptBuilder builder = new();
                        //builder.AppendAudio(_hostingEnvironment.ContentRootPath + $"\\wwwroot\\speech\\notification.wav");
                        builder.AppendText(text);
                        synth.Speak(builder);
                    }
                    catch (Exception e)
                    {
                        _logger.LogInformation("生成语音异常:" + e.Message);
                        throw new Exception("生成语音异常！");
                    }
                    stream.Flush();
                    stream.Seek(0, SeekOrigin.Begin);
                    var result = new FileStreamResult(stream, new MediaTypeHeaderValue("audio/wav"));

                    return result;
                }
            }
            catch (Exception e)
            {
                return new ContentResult { Content = "生成语音失败了！" };
            }

        }

        private string GetMD5(string myString)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] fromData = System.Text.Encoding.Unicode.GetBytes(myString);
            byte[] targetData = md5.ComputeHash(fromData);
            string byte2String = null;
            for (int i = 0; i < targetData.Length; i++)
            {
                byte2String += targetData[i].ToString("x");
            }
            return byte2String;
        }
        /// <summary>
        /// 对输入的文字进行处理
        /// </summary>
        /// <returns></returns>
        private string GetVoidText(string text, string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return text;
            }
            string familyName = name.Substring(0, 1);
            var newFamilyName = familyName
                   .Replace("解", "谢")
                   .Replace("单", "善")
                   .Replace("柏", "佰")
                   .Replace("鲍", "报")
                   .Replace("贲", "奔")
                   .Replace("秘", "币")
                   .Replace("薄", "博")
                   .Replace("卜", "补")
                   .Replace("晁", "潮")
                   .Replace("谌", "陈")
                   .Replace("种", "重")
                   .Replace("秘", "币")
                   .Replace("褚", "储")
                   .Replace("啜", "踹")
                   .Replace("秘", "币")
                   .Replace("郗", "吃")
                   .Replace("邸", "底")
                   .Replace("都", "都")
                   .Replace("费", "费")
                   .Replace("苻", "服")
                   .Replace("干", "干")
                   .Replace("杲", "搞")
                   .Replace("戈", "哥")
                   .Replace("艮", "亘")
                   .Replace("妫", "归")
                   .Replace("缑", "勾")
                   .Replace("都", "都")
                   .Replace("晟", "圣")
                   .Replace("郜", "告")
                   .Replace("句", "苟")
                   .Replace("华", "桦")
                   .Replace("靳", "进")
                   .Replace("宓", "蜜")
                   .Replace("缪", "妙")
                   .Replace("牟", "眸")
                   .Replace("邳", "批")
                   .Replace("朴", "瓢")
                   .Replace("繁", "泼")
                   .Replace("莆", "扑")
                   .Replace("繁", "泼")
                   .Replace("戚", "七")
                   .Replace("谯", "乔")
                   .Replace("覃", "亲")
                   .Replace("仇", "求")
                   .Replace("曲", "屈")
                   .Replace("任", "人")
                   .Replace("阮", "软")
                   .Replace("芮", "瑞")
                   .Replace("少", "哨")
                   .Replace("召", "哨")
                   .Replace("佘", "舍")
                   .Replace("厍", "舍")
                   .Replace("莘", "申")
                   .Replace("折", "蛇")
                   .Replace("折", "乔")
                   .Replace("佟", "同")
                   .Replace("郤", "细")
                   .Replace("冼", "显")
                   .Replace("洗", "显")
                   .Replace("郇", "还")
                   .Replace("乐", "月")
                   .Replace("查", "渣")
                   .Replace("曾", "增");
            Regex r = new(familyName);
            return r.Replace(text, newFamilyName, 1);
        }
    }
}
